import axios, { 
  type AxiosInstance, 
  type AxiosRequestConfig, 
  type AxiosResponse, 
  type InternalAxiosRequestConfig 
} from 'axios'
import { ElMessage, ElLoading } from 'element-plus'

// 响应数据类型定义
export interface ApiResponse<T = any> {
  code: number
  message: string
  data: T
  success: boolean
}

// 请求配置扩展
export interface RequestConfig extends AxiosRequestConfig {
  showLoading?: boolean
  showError?: boolean
  showSuccess?: boolean
}

class HttpRequest {
  private instance: AxiosInstance
  private loading: any = null

  constructor(baseURL: string = '') {
    // 创建axios实例
    this.instance = axios.create({
      baseURL: baseURL || this.getBaseURL(),
      timeout: 10000,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      }
    })

    // 设置请求拦截器
    this.setupRequestInterceptors()
    
    // 设置响应拦截器
    this.setupResponseInterceptors()
  }

  // 获取基础URL
  private getBaseURL(): string {
    if (process.client) {
      // 客户端环境
      return process.env.NODE_ENV === 'production' 
        ? 'https://api.tata-app.com' 
        : 'http://localhost:3000/api'
    } else {
      // 服务端环境
      return process.env.API_BASE_URL || 'http://localhost:3000/api'
    }
  }

  // 设置请求拦截器
  private setupRequestInterceptors(): void {
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 显示加载动画
        if ((config as any).showLoading !== false) {
          this.showLoading()
        }

        // 添加认证token
        const token = this.getToken()
        if (token) {
          config.headers.Authorization = `Bearer ${token}`
        }

        // 添加用户信息
        const userInfo = this.getUserInfo()
        if (userInfo) {
          config.headers['X-User-Info'] = JSON.stringify(userInfo)
        }

        console.log('🚀 Request:', {
          url: config.url,
          method: config.method,
          data: config.data,
          params: config.params
        })

        return config
      },
      (error) => {
        this.hideLoading()
        console.error('❌ Request Error:', error)
        return Promise.reject(error)
      }
    )
  }

  // 设置响应拦截器
  private setupResponseInterceptors(): void {
    this.instance.interceptors.response.use(
      (response: AxiosResponse<ApiResponse>) => {
        this.hideLoading()

        const { data } = response
        
        console.log('✅ Response:', {
          url: response.config.url,
          status: response.status,
          data: data
        })

        // 检查业务状态码
        if (data.code === 200 || data.success) {
          // 显示成功消息
          if ((response.config as any).showSuccess && data.message) {
            ElMessage.success(data.message)
          }
          // 返回修改后的response对象，保持AxiosResponse类型
          return { ...response, data }
        } else {
          // 业务错误处理
          this.handleBusinessError(data, response.config as any)
          return Promise.reject(new Error(data.message || '请求失败'))
        }
      },
      (error) => {
        this.hideLoading()
        console.error('❌ Response Error:', error)
        
        // HTTP错误处理
        this.handleHttpError(error)
        return Promise.reject(error)
      }
    )
  }

  // 业务错误处理
  private handleBusinessError(data: ApiResponse, config: RequestConfig): void {
    if (config.showError !== false) {
      switch (data.code) {
        case 401:
          ElMessage.error('登录已过期，请重新登录')
          this.clearAuth()
          // 跳转到登录页
          if (process.client) {
            window.location.href = '/'
          }
          break
        case 403:
          ElMessage.error('没有权限访问')
          break
        case 404:
          ElMessage.error('请求的资源不存在')
          break
        case 500:
          ElMessage.error('服务器内部错误')
          break
        default:
          ElMessage.error(data.message || '请求失败')
      }
    }
  }

  // HTTP错误处理
  private handleHttpError(error: any): void {
    let message = '网络错误'
    
    if (error.response) {
      // 服务器响应了错误状态码
      const { status } = error.response
      switch (status) {
        case 400:
          message = '请求参数错误'
          break
        case 401:
          message = '未授权访问'
          this.clearAuth()
          break
        case 403:
          message = '禁止访问'
          break
        case 404:
          message = '请求地址不存在'
          break
        case 408:
          message = '请求超时'
          break
        case 500:
          message = '服务器内部错误'
          break
        case 502:
          message = '网关错误'
          break
        case 503:
          message = '服务不可用'
          break
        case 504:
          message = '网关超时'
          break
        default:
          message = `连接错误${status}`
      }
    } else if (error.request) {
      // 请求已发出但没有收到响应
      message = '网络连接失败'
    } else {
      // 其他错误
      message = error.message || '请求失败'
    }

    ElMessage.error(message)
  }

  // 显示加载动画
  private showLoading(): void {
    if (!this.loading) {
      this.loading = ElLoading.service({
        lock: true,
        text: '加载中...',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    }
  }

  // 隐藏加载动画
  private hideLoading(): void {
    if (this.loading) {
      this.loading.close()
      this.loading = null
    }
  }

  // 获取token
  private getToken(): string | null {
    if (process.client) {
      return localStorage.getItem('token') || sessionStorage.getItem('token')
    }
    return null
  }

  // 获取用户信息
  private getUserInfo(): any {
    if (process.client) {
      const userInfo = localStorage.getItem('userInfo')
      return userInfo ? JSON.parse(userInfo) : null
    }
    return null
  }

  // 清除认证信息
  private clearAuth(): void {
    if (process.client) {
      localStorage.removeItem('token')
      localStorage.removeItem('userInfo')
      sessionStorage.removeItem('token')
    }
  }

  // GET请求
  public get<T = any>(
    url: string, 
    params?: any, 
    config?: RequestConfig
  ): Promise<ApiResponse<T>> {
    return this.instance.get(url, { 
      params, 
      ...config 
    })
  }

  // POST请求
  public post<T = any>(
    url: string, 
    data?: any, 
    config?: RequestConfig
  ): Promise<ApiResponse<T>> {
    return this.instance.post(url, data, config)
  }

  // PUT请求
  public put<T = any>(
    url: string, 
    data?: any, 
    config?: RequestConfig
  ): Promise<ApiResponse<T>> {
    return this.instance.put(url, data, config)
  }

  // DELETE请求
  public delete<T = any>(
    url: string, 
    config?: RequestConfig
  ): Promise<ApiResponse<T>> {
    return this.instance.delete(url, config)
  }

  // PATCH请求
  public patch<T = any>(
    url: string, 
    data?: any, 
    config?: RequestConfig
  ): Promise<ApiResponse<T>> {
    return this.instance.patch(url, data, config)
  }

  // 上传文件
  public upload<T = any>(
    url: string, 
    file: File | FormData, 
    config?: RequestConfig
  ): Promise<ApiResponse<T>> {
    const formData = file instanceof FormData ? file : new FormData()
    if (file instanceof File) {
      formData.append('file', file)
    }

    return this.instance.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      ...config
    })
  }

  // 下载文件
  public download(
    url: string, 
    params?: any, 
    filename?: string
  ): Promise<void> {
    return this.instance.get(url, {
      params,
      responseType: 'blob'
    }).then((response: any) => {
      const blob = new Blob([response.data])
      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = filename || 'download'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)
    })
  }

  // 取消请求
  public cancelRequest(message?: string): void {
    // 这里可以实现请求取消逻辑
    console.log('取消请求:', message)
  }
}

// 创建默认实例
const http = new HttpRequest()

// 导出实例和类
export { HttpRequest }
export default http